package com.dl.base.utils

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import com.dl.base.appContext
import com.dl.base.extendsion.isNotNull
import java.io.*
import java.net.NetworkInterface
import java.net.SocketException
import java.util.*


/**
 * 打开指定包名的App应用信息界面
 *
 * @param context     上下文
 * @param packageName 包名
 */
fun openAppInfo(context: Context, packageName: String) {
    val intent = Intent()
    intent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
    intent.data = Uri.parse("package:$packageName")
    context.startActivity(intent)
}

/**
 * 可用来做App信息分享
 *
 * @param context 上下文
 * @param info    分享信息
 */
fun shareAppInfo(context: Context, info: String) {
    val intent = Intent(Intent.ACTION_SEND)
    intent.type = "text/plain"
    intent.putExtra(Intent.EXTRA_TEXT, info)
    context.startActivity(intent)
}

/**
 * 打开App设置中心
 *
 * @param context 上下文
 */
fun openAppSettings(context: Context) {
    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
    val uri = Uri.fromParts("package", context.applicationContext.packageName, null)
    intent.data = uri
    context.startActivity(intent)
}

/**
 * 获取app meta data
 *
 * @param ctx 上下文
 * @param key key
 * @return meta data
 */
fun getAppMetaData(ctx: Context, key: String): String? {
    try {
        val info = ctx.packageManager.getApplicationInfo(
            ctx.packageName,
            PackageManager.GET_META_DATA
        )
        return info.metaData.getString(key)
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }

    return ""
}

/**
 * 获取当前手机系统语言。
 *
 * @return 返回当前系统语言。例如：当前设置的是“中文-中国”，则返回“zh-CN”
 */
fun getSystemLanguage(): String {
    return Locale.getDefault().language
}

/**
 * 获取当前系统上的语言列表(Locale列表)
 *
 * @return 语言列表
 */
fun getSystemLanguageList(): Array<Locale> {
    return Locale.getAvailableLocales()
}

/**
 * 获取当前手机系统版本号
 *
 * @return 系统版本号
 */
fun getSystemVersion(): String {
    return Build.VERSION.RELEASE
}

/**
 * 获取手机型号
 *
 * @return 手机型号
 */
fun getSystemModel(): String {
    return Build.MODEL
}

/**
 * 获取手机厂商
 *
 * @return 手机厂商
 */
fun getDeviceBrand(): String {
    return Build.BRAND
}


/**
 * 获取设备主机地址
 *
 * @return 设备主机地址
 */
fun getDeviceHost(): String {
    return Build.HOST
}

/**
 * 获取设备的唯一标识。由设备的多个信息拼接合成
 *
 * @return 设备唯一标识
 */
fun getDeviceFingerprint(): String {
    return Build.FINGERPRINT
}

/**
 * 获取设备id
 *
 * @return 设备id
 */
@SuppressLint("HardwareIds")
fun getDeviceId(context: Context): String {
    return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
}

/**
 * Android 7.0之后获取Mac地址
 * 遍历循环所有的网络接口，找到接口是 wlan0
 * 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 * @return
 */
private fun getMacFromHardware(): String {
    try {
        val all = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (nif in all) {
            if (!nif.name.equals("wlan0", ignoreCase = true))
                continue
            val macBytes = nif.hardwareAddress ?: return ""
            val res1 = StringBuilder()
            for (b in macBytes) {
                res1.append(String.format("%02X:", b))
            }
            if (!TextUtils.isEmpty(res1)) {
                res1.deleteCharAt(res1.length - 1)
            }
            return res1.toString()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return ""
}

/**
 * Android 6.0-Android 7.0 获取mac地址
 */
private fun getMacAddress(): String? {
    var macSerial: String? = null
    var str: String? = null
    try {
        val pp = Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address")
        val ir = InputStreamReader(pp.inputStream)
        val input = LineNumberReader(ir)
        while (input.readLine()?.also { str = it } != null) {
            macSerial = str!!.trim { it <= ' ' } //去空格
        }
    } catch (ex: IOException) {
        ex.printStackTrace()
    }
    return macSerial
}

/**
 * Android 6.0 之前（不包括6.0）获取mac地址
 * 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
 * @param context * @return
 */
@SuppressLint("HardwareIds")
private fun getMacDefault(context: Context?): String? {
    var mac = ""
    try {
        if (context == null) {
            return mac
        }
        val wifi = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        var info: WifiInfo? = null

        info = wifi.connectionInfo

        if (info == null) {
            return null
        }
        mac = info.macAddress
        if (!TextUtils.isEmpty(mac)) {
            mac = mac.toUpperCase(Locale.ENGLISH)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return mac
}

fun getMac(context: Context): String? {
    return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        getMacDefault(context)
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
        getMacAddress()
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        getMacFromHardware()
    } else {
        ""
    }
}

@SuppressLint("PrivateApi", "WrongConstant")
fun getDeviceMac(): String {
    val defaultMac = "00:00:00:00:00:00"
    var mac: String? = null
    try {
        val cla = Class.forName("android.net.EthernetManager")
        val method = cla.getDeclaredMethod("getEthernetMacAddress", String::class.java)
        method.isAccessible = true
        val service: Any = appContext.getSystemService("ethernet")
        val obj = method.invoke(service, "eth0")
        obj?.let {
            mac = obj.toString()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    if (!mac.isNotNull()) {
        mac = readFromDevice(File("/sys/class/net/wlan0/address"))
    }
    return if (mac.isNotNull()) {
        mac!!
    } else {
        getMac(appContext) ?: defaultMac
    }
}

private fun readFromDevice(device: File): String {
    var result = ""
    if (device.exists()) {
        if (!device.canRead() || !device.canWrite()) {
            excuseCmd("vm -c 'chmod 666 " + device.absolutePath + "'")
        }
        try {
            result = BufferedReader(FileReader(device)).readLine()
        } catch (var3: IOException) {
            var3.printStackTrace()
        }
    }
    return result
}

fun excuseCmd(command: String) {
    var process: Process? = null
    var os: DataOutputStream? = null
    try {
        process = Runtime.getRuntime().exec("vm")
        os = DataOutputStream(process.outputStream)
        os.writeBytes("$command\n")
        os.writeBytes("exit\n")
        os.flush()
        process.waitFor()
    } catch (var12: java.lang.Exception) {
        var12.printStackTrace()
    } finally {
        try {
            os?.close()
            process?.destroy()
        } catch (var11: java.lang.Exception) {
            var11.printStackTrace()
        }
    }
}

/**
 * 获取应用程序名称
 */
fun getAppName(context: Context): String? {
    try {
        val packageManager = context.packageManager
        val packageInfo = packageManager.getPackageInfo(
            context.packageName, 0
        )
        val labelRes = packageInfo.applicationInfo.labelRes
        return context.resources.getString(labelRes)
    } catch (e: Exception) {
        e.printStackTrace()
    }

    return null

}

/**
 * 获取应用程序版本名称信息
 *
 */
fun getVersionName(context: Context): String? {
    try {
        val packageManager = context.packageManager
        val packageInfo = packageManager.getPackageInfo(
            context.packageName, 0
        )
        return packageInfo.versionName
    } catch (e: Exception) {
        e.printStackTrace()
    }

    return null
}


fun getIP(context: Context): String {
    try {
        val ipv: String
        val nilist = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (ni in nilist) {
            val ialist = Collections.list(ni.inetAddresses)
            for (address in ialist) {
                if (!address.isLoopbackAddress && !address.isLinkLocalAddress) {
                    ipv = address.hostAddress
                    return ipv
                }
            }
        }
    } catch (ex: SocketException) {
        ex.printStackTrace()
    }
    return "127.0.0.1"
}



